"""
Trading Service API Routes
==========================

This module defines the FastAPI routes for the trading service.

It uses a dependency injection pattern to provide the database session and
the trading service instance to the route handlers.
"""
from typing import List, Tuple
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from ..services.trading_service import TradingService
from ..schemas.trading_schemas import (
    OrderRequest, OrderUpdate, OrderQueryParams, TradeQueryParams,
    PositionQueryParams, ContractQueryParams, GatewayRequest,
    StrategyRequest, StrategyControlRequest, TradingStatistics
)
from ..core.exceptions import (
    TradingServiceError, OrderNotFoundError, InsufficientFundsError,
    GatewayNotConnectedError, StrategyNotFoundError, RiskCheckFailedError
)
# This dependency will be created in main.py
from ..main import get_db_session, get_trading_service


router = APIRouter(
    prefix="/api/v1/trading",
    tags=["Trading"],
    responses={404: {"description": "Not found"}},
)


# ==================== Dependency Injection ====================

# We can define dependencies here to get the service and session
# These will be wired up in the main application file.

# ==================== Order Management Routes ====================

@router.post("/orders", status_code=201)
async def create_order(
    order_request: OrderRequest,
    user_id: str = "user_placeholder",  # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Create a new trading order.
    """
    try:
        result = await trading_service.create_order(session, user_id, order_request)
        return result
    except (RiskCheckFailedError, InsufficientFundsError, GatewayNotConnectedError) as e:
        raise HTTPException(status_code=400, detail=str(e))
    except TradingServiceError as e:
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/orders/{order_id}/cancel", status_code=200)
async def cancel_order(
    order_id: str,
    reason: str = Query(None, description="Reason for cancellation"),
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Cancel an existing trading order.
    """
    try:
        success = await trading_service.cancel_order(session, user_id, order_id, reason)
        if success:
            return {"message": "Order cancelled successfully"}
    except OrderNotFoundError as e:
        raise HTTPException(status_code=404, detail=str(e))
    except TradingServiceError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/orders")
async def get_orders(
    params: OrderQueryParams = Depends(),
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get a list of trading orders based on query parameters.
    """
    orders, total = await trading_service.get_orders(session, user_id, params)
    return {"orders": orders, "total": total}


@router.get("/orders/{order_id}")
async def get_order_detail(
    order_id: str,
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get the details of a specific order.
    """
    order = await trading_service.get_order_detail(session, user_id, order_id)
    if not order:
        raise HTTPException(status_code=404, detail="Order not found")
    return order

# ==================== Trade Management Routes ====================

@router.get("/trades")
async def get_trades(
    params: TradeQueryParams = Depends(),
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get a list of trades based on query parameters.
    """
    trades, total = await trading_service.get_trades(session, user_id, params)
    return {"trades": trades, "total": total}

# ==================== Position Management Routes ====================

@router.get("/positions")
async def get_positions(
    params: PositionQueryParams = Depends(),
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get a list of current positions.
    """
    positions, total = await trading_service.get_positions(session, user_id, params)
    return {"positions": positions, "total": total}

# ==================== Account Management Routes ====================

@router.get("/accounts")
async def get_accounts(
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get a list of trading accounts for a user.
    """
    accounts = await trading_service.get_accounts(session, user_id)
    return {"accounts": accounts}

# ==================== Statistics Routes ====================

@router.get("/statistics")
async def get_trading_statistics(
    user_id: str = "user_placeholder", # Placeholder for auth
    session: AsyncSession = Depends(get_db_session),
    trading_service: TradingService = Depends(get_trading_service)
):
    """
    Get trading statistics for a user.
    """
    stats = await trading_service.get_trading_statistics(session, user_id)
    return stats